Forked from davidrleonard/add-team-to-repos.js
Last active
February 18, 2022 22:46
-
-
Save otherguy/4170eaff211f5e43ba98ba78f4a704be to your computer and use it in GitHub Desktop.
Add a new team to all Github repos in an organization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Adds a team to all the repos in a Github organization. This is a tedious | |
* process in the UI. | |
* | |
* Instructions: | |
* | |
* 1. Copy this file somewhere 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 = 'YOUR_GITHUB_ORG_NAME'; /* Name of the github organization the team is under and the repos are in */ | |
const GITHUB_ACCESS_TOKEN = 'YOUR_GITHUB_ACCESS_TOKEN'; /* Create an access token here: https://github.com/settings/tokens */ | |
const TEAM_NAME = 'GITHUB_TEAM_NAME'; /* Github team name */ | |
const TEAM_PERMISSION = 'CHOSEN_PERMISSION'; /* 'pull' or 'push' or 'admin' */ | |
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\"/gi; | |
const nextPageMatch = nextPageRe.exec(response); | |
const nextPage = nextPageMatch ? nextPageMatch[1] : null; | |
const repos = JSON.parse(response.slice(response.indexOf('['))); | |
return [repos, nextPage]; | |
} | |
async function getTeamId(org, team) { | |
const [response] = await execPromise( | |
`curl -H "Authorization: token ${GITHUB_ACCESS_TOKEN}" https://api.github.com/orgs/${org}/teams/${team}` | |
); | |
const teamDetails = JSON.parse(response); | |
if (!teamDetails.id) { return null; } | |
return teamDetails.id; | |
} | |
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(teamId, org, repo, permission) { | |
const [out,err] = await execPromise( | |
`curl -X PUT -H "Authorization: token ${GITHUB_ACCESS_TOKEN}" -d '{"permission":"${permission}"}' https://api.github.com/teams/${teamId}/repos/${org}/${repo}` | |
); | |
console.log(`... Added team "${teamId}" to repo "${org}/${repo}" with permission "${permission}"`); | |
} | |
(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`) | |
console.log(`Fetching id for team "${TEAM_NAME}" in organization "${GITHUB_ORG}"`); | |
const teamId = await getTeamId(GITHUB_ORG, TEAM_NAME); | |
if (teamId == null) { | |
console.error(`... Could not find team "${TEAM_NAME}" in organization "${GITHUB_ORG}"`); | |
process.exit(1); | |
} | |
console.log(`... Found ID ${teamId} for team "${TEAM_NAME}"`) | |
/* Add team to each repo */ | |
console.log(`Adding team "${TEAM_NAME}" to ${repoNames.length} repos with permission "${TEAM_PERMISSION}"`); | |
for (let repo of repoNames) { | |
await addTeamToRepo(teamId, GITHUB_ORG, repo, TEAM_PERMISSION); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment