# repo-automation-bots: eighteen Probot bots for the chores of running a repo

> googleapis/repo-automation-bots is a monorepo of GitHub Apps built on Probot that perform the repetitive parts of repository maintenance, from labelling and auto-approval to release proposals and flaky build detection. It is Apache-2.0 licensed, written in TypeScript, and shaped by the needs of Google's own open source organisation rather than by a general purpose design.

**googleapis/repo-automation-bots** — A collection of bots, based on probot, for performing common maintenance tasks across the open-source repos managed by Google on GitHub.

- Repository: https://github.com/googleapis/repo-automation-bots
- Stars: 747 · Forks: 173
- Language: TypeScript
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/googleapis-repo-automation-bots

## Eighteen small apps rather than one configurable app

The repository describes itself as a collection of bots, based on probot, for performing common maintenance tasks across the open source repos managed by Google on GitHub.

The list of implemented bots is the substance of the project, and reading it tells you what a large organisation actually needs done. There are three that act on issues and pull requests as they arrive: auto-approve, which automatically approves and merges pull requests matching user-specified configs; auto-label, which labels issues and pull requests with product, language or directory based labels; and blunderbuss, which assigns issues and pull requests randomly to a specific list of users.

Then there is a larger group of pull request checkers, each enforcing one rule. conventional-commit-lint checks that commit messages follow conventionalcommits.org style. do-not-merge ensures the do not merge label is not present. generated-files-bot notifies if you are modifying generated files. license-header-lint ensures source files contain valid license headers. repo-metadata-lint lints .repo-metadata.json files. snippet-bot checks for mismatched region tags in pull requests. policy checks repository configuration against known rules.

And then the automation side: cherry-pick-bot cherry-picks merged pull requests between branches, merge-on-green merges a pull request when all required checks have passed, release-please proposes releases based on semantic version commits, release-trigger triggers releases jobs, failurechecker looks for automation tasks such as releases that are in a failed state, label-sync synchronizes labels across organizations, sync-repo-settings synchronizes repository settings from a centralized config, trusted-contribution allows Kokoro CI to trigger for trusted contributors, and flakybot listens on a PubSub queue for broken builds and opens corresponding issues.

The design decision is worth stating plainly. Each bot is a separate package under packages/, and each is a small Probot app with a single job. A bot that does one thing can be installed on one repository without dragging the rest of the toolkit with it, which is exactly what a large fleet of repos needs.

## Probot supplies the app model, and the repo adds the fleet plumbing

The bots are Probot apps, which is the decision that makes them conventional GitHub Apps rather than custom webhook handlers. A Probot app gets its identity, its installation model and its event handling from the framework, so what is left in each package is the actual behaviour.

The repository root shows the fleet-level concerns. There is a .repo-metadata.json at the top level, which is the same file the repo-metadata-lint bot checks, suggesting the org keeps a machine-readable description of each repository. A .release-please-manifest.json and a release-please-config.json drive the release-please bot across the monorepo. renovate.json5 handles dependency updates. A .c8rc file configures code coverage, and the test script is wired through c8.

The scripts in the root manifest show the workflow model, and they are unusual enough to be worth reading closely. The run script is a plain node invocation of a local script, and the fix, test and other scripts all route through it, so one entry point fans out to every package.

```json
  "scripts": {
    "run": "./scripts/scripts.js",
    "fix": "npm run run -- npm run fix",
    "test": "c8 npm run run -- npm test",
    "proxy": "smee",
    "generate-bot": "node ./packages/generate-bot/run.js"
  },
```

The test script wraps the whole fan-out in c8 for coverage, and the proxy script is just smee, the webhook relay client, which is what the development setup depends on. The last script is the interesting one: generate-bot runs a generator in the packages/generate-bot directory, so a new bot starts from a template rather than from an empty directory.

Other top level entries point at the deployment story. There is a cloudbuild.yaml and a cloudbuild-cve-scan.yaml, so the bots are built by Google Cloud Build with a separate pipeline for scanning for known vulnerabilities. There is a serverless-scheduler-proxy directory, which relates to the cron support, a trigger-sync directory, a metrics directory, and an architecture.png that the README points to for the overall architecture.

The release tags show the packages are published individually. gcf-utils is at v17.2.2, mono-repo-publish at v1.8.1 and label-utils at v6.2.1, each with its own version line, which confirms the packages are independently consumed and independently versioned.

## Running a bot locally means a webhook relay, a GitHub App and four environment variables

The development setup in the README is specific enough to follow, and it is the same setup any Probot app needs.

The first problem is getting GitHub webhooks to reach your laptop. The answer is smee.io, a service that relays webhooks. You create a proxy there and get a URL back, then run the proxy script in the repository root with that URL.

```bash
npm run proxy -- -u <URL-OF-PROXY>
```

The second step is creating the GitHub App itself, which the README does with the probot server. You change into the package you are working on, start it, and visit the local server to install the app.

```bash
cd packages/your-bot
npm start
```

The server listens on port 3000, and the README says to visit http://localhost:3000 and install. That installation step creates the app and gives you the credentials you need next.

Third, the permissions. A newly created app has no permissions by default, so you go to the installation settings page, configure, and then to app settings, and under Permissions and Events you grant what the bot needs. The README names the likely candidate, Repository and Pull Requests, and reminds you to subscribe to the corresponding events, for instance Events and Pull Request if the bot responds to pull request activity.

Fourth, the environment. Running the app again with variables set, most of which are found on the GitHub app settings page.

- `APP_ID`: the ID, listed near the top as App ID: 12345
- `PRIVATE_KEY_PATH`: path to the app's private key, which you can request and download from the bottom of the page
- `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET`: the alternative to the private key, taken from the top of the page
- `WEBHOOK_SECRET`: a secret key set in the GitHub developer settings, which you edit to a known value

That is the whole loop: relay, install, grant, configure, run. The project requires Node.js 12 or higher according to the development section, while the root manifest now declares an engines field requiring Node 22 or later, and the README suggests nvm if you need to manage multiple Node versions.

The Node version discrepancy is worth noting. The prose is older than the manifest, and the manifest is the one your install will enforce.

## Cron support turns a bot into a scheduled job

One feature stands out because it is not a webhook bot at all. To run a bot on a schedule you include a file in the bot's folder named cron whose content is valid unix cron format.

The consequence is that the bot's own endpoint becomes a scheduled endpoint, and the README says it plainly: this creates a Cloud Scheduler Job which makes requests to your endpoint at the specified schedule.

That is a neat trick. The bot needs no separate scheduler, no queue and no extra infrastructure, because the trigger is the same HTTP endpoint the app already serves. A file named cron with a crontab line is the entire configuration.

Which bots want this is easy to guess from the list. failurechecker exists to look for automation tasks such as releases that are in a failed state, and that is a periodic sweep rather than an event response. label-sync and sync-repo-settings are the same kind of thing, reconciling labels and repository settings against a centralized source on a schedule rather than reacting to a single push.

The other direction is also covered. trusted-contribution allows Kokoro CI to trigger for trusted contributors, which is a different mechanism again: the bot adjusts a permission or trigger rule so that the CI system behaves differently depending on who opened the pull request. And flakybot closes the loop from the other side, listening on a PubSub queue for broken builds and opening corresponding issues, which means the bot consumes from Google infrastructure rather than only from GitHub.

The publishing path for shared modules is short. The README says to create a token with Wombat Dressing Room and then run npm run release. Wombat Dressing Room is linked to a Google open source blog post about npm publication, and the release tags confirm the pattern: gcf-utils, mono-repo-publish and label-utils are all published as separate npm packages, so a bot can depend on a shared utility from a registry rather than vendoring it.

## Where repo-automation-bots is the wrong tool

The first wrong-tool case is a small project. Every bot here is a GitHub App that needs a registered application, credentials, a webhook endpoint and permission configuration. For a single repository with a single maintainer, a GitHub Action in a workflow file is fewer moving parts, and there is nothing to install, no app registration and no secret to manage beyond the ones GitHub Actions already uses.

The second case is an organisation that wants one configurable bot rather than a fleet. The design here is many single-purpose apps, and there is no single bot you configure to do labelling plus approval plus releases with one set of settings. If you want that, a different shape of tool fits better.

The third case is a repository set with no shared conventions. Many of these bots encode assumptions: label names, the .repo-metadata.json file, conventional commit messages, license headers, the release-please manifest, a centralized repository settings source, the region tags that snippet-bot checks. An organisation that has not agreed on those conventions gets the mechanics without the benefit, and ends up writing configuration to satisfy the bots rather than the other way round.

There is also a scope limit that follows from the origin. The README contains a note to Googlers asking them to contribute, and the repository is the Google one, so the priority order for changes and the release process reflect one organisation's needs. The code is Apache-2.0 licensed, so you can use and modify it freely, but you should expect to do the maintenance yourself.

One operational caution that applies to any automation of this kind. auto-approve and merge-on-green act on pull requests without asking, and blunderbuss assigns work at random to real people. Every one of those is a good idea only if the checks it relies on are trusted, and a bad configuration in one repository can approve and merge work in a hundred others once the app is installed organisation wide. Scope the installation to specific repositories, which is the option the README's install step describes, and read the label and policy configuration before you flip a bot on for a repository that has real contributors.

## Conclusion

repo-automation-bots suits an organisation that runs many public repositories with a shared configuration and wants the labelling, approval, linting and release chores handled by the same apps everywhere, since the packages are independently publishable and each one is a small Probot app you can install per repository. It does not suit a team with one or two repos, where a GitHub Action or a small workflow will do the same job in fewer lines. Before adopting, read the bot list against what your own maintainers actually spend time on, and note that the project is organised around Google's own repository conventions, so the label names, the release tooling and the policy checks carry assumptions you will meet as configuration rather than as defaults.

## FAQ

### What is googleapis/repo-automation-bots?

It is a collection of bots, based on probot, for performing common maintenance tasks across the open source repos managed by Google on GitHub. The bots cover labelling, auto-approval, PR checkers, release automation, label and settings sync, and flaky build detection, each as a separate package.

### How do I run a repo-automation-bots bot locally?

Create a webhook relay proxy at smee.io and run npm run proxy -- -u <URL-OF-PROXY> in the repository root, then create a GitHub App with the probot server by running npm start in the bot's package and visiting http://localhost:3000 to install, then grant the needed permissions and events and set APP_ID, PRIVATE_KEY_PATH or the client id and secret, and WEBHOOK_SECRET.

### How do I run a repo-automation-bots bot on a schedule?

Include a file named cron in the bot's folder whose content is valid unix cron format. That creates a Cloud Scheduler Job which makes requests to the bot's endpoint at the specified schedule.

### What Node.js version does repo-automation-bots need?

The development section of the README says node.js version 12 or higher and suggests nvm for managing multiple versions, while the root package.json declares an engines field requiring Node 22 or later. The manifest is what an install enforces.

### What license is repo-automation-bots released under?

The project is licensed under Apache-2.0, declared in the root package.json with a LICENSE file at the root of the repository. The packages are published individually to npm, for example gcf-utils, mono-repo-publish and label-utils.

## Sources

- [googleapis/repo-automation-bots on GitHub](https://github.com/googleapis/repo-automation-bots)
- [Issues](https://github.com/googleapis/repo-automation-bots/issues)
- [License: Apache-2.0](https://github.com/googleapis/repo-automation-bots/blob/main/LICENSE)
- [README](https://github.com/googleapis/repo-automation-bots/blob/main/README.md)
- [Releases](https://github.com/googleapis/repo-automation-bots/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/googleapis-repo-automation-bots
