{"id":13996025,"url":"https://github.com/googleapis/github-repo-automation","last_synced_at":"2025-10-08T08:31:18.870Z","repository":{"id":30613394,"uuid":"125540980","full_name":"googleapis/github-repo-automation","owner":"googleapis","description":"A set of tools to automate multiple GitHub repository management.","archived":false,"fork":false,"pushed_at":"2024-11-21T22:42:46.000Z","size":1222,"stargazers_count":178,"open_issues_count":19,"forks_count":37,"subscribers_count":51,"default_branch":"main","last_synced_at":"2025-01-19T10:03:13.757Z","etag":null,"topics":["api","github"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/googleapis.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-16T16:17:08.000Z","updated_at":"2024-12-02T21:08:15.000Z","dependencies_parsed_at":"2024-07-06T12:22:26.961Z","dependency_job_id":"71c69c21-de98-4a93-aa1c-8967155c6f78","html_url":"https://github.com/googleapis/github-repo-automation","commit_stats":{"total_commits":517,"total_committers":30,"mean_commits":"17.233333333333334","dds":0.8355899419729207,"last_synced_commit":"496b45a986699b26bd0cd1dd4844edc256ffd19c"},"previous_names":[],"tags_count":42,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleapis%2Fgithub-repo-automation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleapis%2Fgithub-repo-automation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleapis%2Fgithub-repo-automation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/googleapis%2Fgithub-repo-automation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/googleapis","download_url":"https://codeload.github.com/googleapis/github-repo-automation/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235694178,"owners_count":19030772,"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":["api","github"],"created_at":"2024-08-09T14:03:44.309Z","updated_at":"2025-10-08T08:31:18.440Z","avatar_url":"https://github.com/googleapis.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"**_THIS REPOSITORY IS DEPRECATED._**\n\n\u003cimg src=\"https://avatars0.githubusercontent.com/u/1342004?v=3\u0026s=96\" alt=\"Google Inc. logo\" title=\"Google\" align=\"right\" height=\"96\" width=\"96\"/\u003e\n\n# GitHub Repo Automation\n\u003e A set of tools to automate multiple GitHub repository management.\n\n**This is not an officially supported Google product.**\n\nAs we publish Node.js client libraries to multiple repositories under\n[googleapis](https://github.com/googleapis/), we need a set of small\ntools to perform management of those repositories, such as updating\ncontinuous integration setup, updating dependencies, and so on.\n\nThis repository contains some scripts that may be useful for this kind\nof tasks.\n\n## Installation\n\n**Googlers**: You should install this tool on your laptop\nor workstation, as folks have run into timeout issues when using\na Google Cloud Compute Engine instance.\n\nIf you're not familiar with Node.js development you can still\nuse the tools included as they don't require writing any Javascript\ncode. Before running the scripts, make sure you have Node.js version 8+\ninstalled (e.g. from [here](https://nodejs.org/en/)) and available in\nyour `PATH`, and install the required dependencies:\n\n```sh\n$ npm install -g @google/repo\n```\n\nYou need to make your own [`config.yaml`](https://github.com/googleapis/github-repo-automation/blob/main/config.yaml.default) and put your GitHub token there. Example:\n\n```\nbaseUrl: https://git.mycompany.com/api/v3 # optional, if you are using GitHub Enterprise\ngithubToken: your-github-token\nclonePath: /User/my-user/.repo # optional\nrepoSearch: org:googleapis language:typescript language:javascript is:public archived:false\n```\n\nThe `repoSearch` field uses the [GitHub Repository Search syntax](https://help.github.com/en/github/searching-for-information-on-github/searching-for-repositories).\n\nYou can set the path to the config file with the `REPO_CONFIG_PATH` environment variable:\n\n```sh\n$ echo $REPO_CONFIG_PATH\n/User/beckwith/config.yaml\n```\n\nNow you are good to go!\n\n## Usage\n\n### PR based workflows\n\nThe following commands operate over a collection of PRs.\n\n#### repo approve\n\n```sh\n$ repo approve [--title title]\n```\n\nIterates over all open pull requests matching `title` (this can be a regex,\nand all PRs will be processed if no regex for title is given) in all configured repositories.\nFor each pull request, asks (in console) if it should be approved\nand merged. Useful for managing GreenKeeper's PRs:\n\n`$ repo approve 🚀`\n\nor all PRs with the word `test` in the title:\n\n`$ repo approve test`\n\n#### repo list\n\n```sh\n$ repo list [--title title]\n```\n\nIterates over all open pull requests matching `title` (this can be a regex,\nand all PRs will be processed if no regex for title is given)\nin all configured repositories, and prints them.\n\n`$ repo list --title 🚀`\n\nor all PRs with the word `test` in the title:\n\n`$ repo list --title test`\n\n#### repo reject\n\n```sh\n$ repo reject [--title title] [--clean]\n```\n\nIterates over all open pull requests matching `title` (this can be a regex,\nand all PRs will be processed if no regex for title is given) and closes\nthem. For example, close all PRs with the word `test` in the title:\n\n`$ repo reject --title test`\n\nIf `--clean` is specified, the branch associated with the PR will also be deleted. Branches on forked PRs will be ignored.\n\n#### repo rename\n\n```sh\n$ repo rename --title title 'new title'\n```\n\nIterates over all open pull requests matching `title` (this can be a regex,\nand all PRs will be processed if no regex for title is given), and renames\nthem.\n\n#### repo apply\n\n```sh\n$ repo apply --branch branch\n             --message message\n             --comment comment\n             [--reviewers username[,username...]]\n             [--silent]\n             command\n```\n\nIterates over all configured repositories, clones each of them into\na temporary folder, and runs `command` to apply any changes you need.\nAfter `command` is run, `git status` is executed and all added and\nchanged files are committed into a new branch `branch` with commit message\n`message`, and then a new pull request is created with comment `comment`\nand the given list of reviewers.\n\nPlease note that because of GitHub API [does not\nsupport](https://github.com/isaacs/github/issues/199) inserting multiple files\ninto one commit, each file will be committed separately. It can be fixed by\nchanging this library to use the low-level\n[Git data API](https://developer.github.com/v3/git/),\nyour contributions are welcome!\n\n#### repo check\n\n```sh\n$ repo check\n```\n\nIterates all configured repositories and checks that each repository\nis configured properly (branch protection, continuous integration,\nvalid `README.md`, etc.).\n\n### Repository based workflows\nIn some cases, you may want to clone all of the repositories that match a given filter, and perform operations over them all locally.\n\n#### repo sync\nTo clone or reset all repositories in a given filter set, run:\n\n```sh\n$ repo sync\n```\n\nThis will clone all repositories in the configured `clonePath`.  From there, you can open the entire codebase in your favorite editor, and make changes.\n\n#### repo exec\nAfter cloning all repositories and making a set of batch changes, you will likely want to commit those changes, push upstream, and submit a pull request.  For these, you can use `repo exec`.  This command executes a given command over every cloned repository brought in via `repo sync`:\n\n```sh\n$ repo exec -- git status\n```\n\nFor example - to go through a typical PR workflow, you would run:\n\n```sh\n$ repo exec -- git checkout -b my-branch-name\n$ repo exec -- git add -A\n$ repo exec -- git commit -m \\\"chore: do something fun\\\"\n$ repo exec -- git push origin my-branch-name\n$ repo exec --concurrency 1 -- gh pr create --fill\n```\n\nThe `gh` tool referenced above uses https://cli.github.com/, and the `--concurrency` flag allows you to control how many pull requests are sent to the GitHub API at once.  This is useful if you run into rate limiting or abuse errors.\n\n## List of libraries\n\nThe tools listed above use the following libraries available in `lib/` folder.\nFeel free to use them directly from your JavaScript code if you need more\nflexibility than provided by the tools. The files in `samples/` folder\ncan serve as samples that show library usage.\n\n### `lib/update-repo.js`\n\nIterates over all configured repositories, clones each of them into\na temporary folder, and calls the provided function to apply any changes you\nneed. The function must return a promise resolving to the list of files to\ncreate or modify. These files are committed into a new branch with the given\ncommit message, and then a new pull request is created with the given comment\nand the given list of reviewers.\n\nPlease note that because of GitHub API [does not\nsupport](https://github.com/isaacs/github/issues/199) inserting multiple files\ninto one commit, each file will be committed separately. It can be fixed by\nchanging this library to use the low-level\n[Git data API](https://developer.github.com/v3/git/),\nyour contributions are welcome!\n\n```js\nconst updateRepo = require('./lib/update-repo.js');\n\nasync function callbackFunction(repoPath) {\n  // make any changes to the cloned repo in repoPath\n  let files = ['path/to/updated/file', 'path/to/new/file'];\n  return Promise.resolve(files);\n}\n\nasync function example() {\n  await updateRepo({\n    updateCallback: callbackFunction,\n    branch: 'new-branch',\n    message: 'commit message',\n    comment: 'pull request comment',\n    reviewers: ['github-username1', 'github-username2'],\n  });\n}\n```\n\n### `lib/update-file.js`\n\nA function that applies the same fix to one file in all configured\nrepositories, and sends pull requests (that can be approved and merged\nlater by `approve-pr.js` or manually). Useful if you need to make\nthe same boring change to all the repositories, such as change some\nconfiguration file in a certain way.\n\n```js\nconst updateFile = require('./lib/update-file.js');\n\nfunction callbackFunction(content) {\n  let newContent = content;\n  // make any changes to file content\n  return newContent;\n}\n\nasync function example() {\n  await updateFile({\n    path: 'path/to/file/in/repository',\n    patchFunction: callbackFunction,\n    branch: 'new-branch',\n    message: 'commit message',\n    comment: 'pull request comment',\n    reviewers: ['github-username1', 'github-username2'],\n  });\n}\n```\n\n### `lib/update-file-in-branch.js`\n\nA function that does pretty much the same, but to the file in the\ngiven branch in all configured repositories, and does not send any\npull requests. Useful if you created a bunch of PRs using `update-file.js`, but\nthen decided to apply a quick change in all created branches.\n\n```js\nconst updateFileInBranch = require('./lib/update-file-in-branch.js');\n\nfunction callbackFunction(content) {\n  let newContent = content;\n  // make any changes to file content\n  return newContent;\n}\n\nasync function example() {\n  await updateFileInBranch({\n    path: 'path/to/file/in/repository',\n    patchFunction: callbackFunction,\n    branch: 'existing-branch',\n    message: 'commit message',\n  });\n}\n```\n\n### Other files in `lib/`\n\n#### `lib/github.js`\n\nA simple wrapper to GitHub client API\n([@octokit/rest](https://github.com/octokit/rest.js)) that at least lets you\npass less parameters to each API call.\n\n#### `lib/question.js`\n\nA promisified version of `readline.question` to provide some primitive\ninteraction.\n\n## Handling large numbers of repositories\n\nIf you are running GitHub Repo Automation against a large number of repositories, you may find that\nthe default settings lead to quota issues.\n\nThere are settings you can configure to make this less likely:\n\n1. Set `--concurrency=N` to reduce the # of concurrent requests you are performing:\n  ```bash\n  repo approve --concurrency=4 --title='.*foo dep.*'\n  ```\n2. Set `--retry` to automatically retry exceptions with an exponential backoff:\n  ```\n  repo approve --retry --title='.*foo dep.*'\n  ```\n3. Set `--delay=N` to introduce a delay between requests, allowing you to spread out operations over a longer timeframe:\n  ```\n  repo approve --delay=2500\n  ```\n\nWhen running against a large number of repos, try the following as a starting point:\n\n```bash\nrepo [command] --delay=1000 --concurrency=2 --retry --title='.*some title.*'\n```\n\nIf you are continuing to run into problems, run with:\n\n```\nNODE_DEBUG=repo repo [command] --delay=1000 --concurrency=2 --retry --title='.*some title.*'\n```\n\nAnd share the debug output in an issue, along with the command you are running.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogleapis%2Fgithub-repo-automation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoogleapis%2Fgithub-repo-automation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoogleapis%2Fgithub-repo-automation/lists"}