Skip to content

Instantly share code, notes, and snippets.

@skwid138
Forked from davidrleonard/add-team-to-repos.js
Last active September 12, 2022 16:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skwid138/95702ac50fc7fd9ceb57da5f7384b1e7 to your computer and use it in GitHub Desktop.
Save skwid138/95702ac50fc7fd9ceb57da5f7384b1e7 to your computer and use it in GitHub Desktop.
Add a new team to all Github repos in an organization
/*
* Adds the specificed team to all the repos in a Github organization.
* This is a tedious process in the UI.
* You'll need a version of node greater than 9 to run this
*
* https://docs.github.com/en/rest/teams/teams#add-or-update-team-repository-permissions
*
* Instructions:
* 1. Copy this file somewhere locally on your computer, e.g. ~/addteamrepos.js
* 2. Fill in the uppercase variables below with the right values
* 3. Run this file: `$ node ~/addteamrepos.js`
*/
const GITHUB_ORG = 'xxxxx'; /* Name of the github organization the team is under and the repos are in */
const GITHUB_ACCESS_TOKEN = 'xxxxxxxxxxxxxxxxxxxxxxx'; /* Create an access token here: https://github.com/settings/tokens */
const TEAM_SLUG = 'team-name'; /* Github team slug, this can be pulled from the URL on the website */
const TEAM_PERMISSION = 'push'; /* 'pull', 'triage', 'push', 'maintain, or 'admin' */
const REPO_OWNER = 'name-of-owner' /* Likely the same as the organization */
const { exec } = require('child_process');
function execPromise(command) {
return new Promise((resolve, reject) => {
exec(command, (err, stdout, stderr) => {
if (err) {
return reject(err);
}
resolve([stdout, stderr]);
});
});
}
async function fetchReposPage(org, page) {
const [response] = await execPromise(
`curl -i -H "Authorization: token ${GITHUB_ACCESS_TOKEN}" https://api.github.com/orgs/${org}/repos?page=${page}`
);
const nextPageRe = /link\: \<.+page\=([0-9]*)\>\; rel\=\"next\"/g;
const nextPageMatch = nextPageRe.exec(response);
const nextPage = nextPageMatch ? nextPageMatch[1] : null;
const repos = JSON.parse(response.slice(response.indexOf('[')));
return [repos, nextPage];
}
async function fetchRepos(org) {
let repos = [];
let page = 1;
while (page) {
let [currentRepos, nextPage] = await fetchReposPage(org, page);
repos = [...repos, ...currentRepos];
page = nextPage;
}
return repos;
}
async function addTeamToRepo(teamSlug, org, repo, permission, owner) {
const [out,err] = await execPromise(
`curl -X PUT -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${GITHUB_ACCESS_TOKEN}" https://api.github.com/orgs/${org}/teams/${teamSlug}/repos/${owner}/${repo} -d \"{\\"permission\\":\\"${permission}\\"}\"`
);
console.log(out); // This allows for debugging, but is typically empty on success
console.log(`... Added team "${teamSlug}" to repo "${org}/${repo}" with permission "${permission}"`);
}
async function addTeamToRepos(repoNames) {
/* Add team to each repo */
console.log(`Adding team "${TEAM_SLUG}" to ${repoNames.length} repos with permission "${TEAM_PERMISSION}"`);
for (let repo of repoNames) {
await addTeamToRepo(TEAM_SLUG, GITHUB_ORG, repo, TEAM_PERMISSION, REPO_OWNER);
}
}
(async () => {
/* Fetch all repos names for org */
console.log(`Fetching repos from organization "${GITHUB_ORG}"`);
const repos = await fetchRepos(GITHUB_ORG);
const repoNames = repos.map(r => r.name);
console.log(`... Found ${repoNames.length} repos`)
await addTeamToRepos(repoNames);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment