Skip to content

Instantly share code, notes, and snippets.

@baztian
Forked from xalvarez/get_repos.sh
Last active February 2, 2022 21:09
Show Gist options
  • Save baztian/d6a45e7408d1d4bdae67479a2bda73f4 to your computer and use it in GitHub Desktop.
Save baztian/d6a45e7408d1d4bdae67479a2bda73f4 to your computer and use it in GitHub Desktop.
Clone and fork a team's first 100 GitHub repos. Then, add remotes for all potential forks.
#!/usr/bin/env bash
# Clone and fork a team's first 100 GitHub repos. Then, add remotes for all potential forks.
#
# Requires:
# - git: https://git-scm.com/downloads
# - github-cli: https://github.com/cli/cli
# - jq: https://stedolan.github.io/jq/download/
#
# The first time you run this script or use gh for the first time in your system
# you need to authenticate yourself as follows:
# gh auth login
function printHelp {
echo "usage: $(basename "$0") [-f] [-m] <organization> <team> [<teamMemberToIgnore> ...]"
echo " -h Print this help."
echo " -f Create a fork for the repository."
echo " -m Add remote for all team member forks of the repositories."
echo " organization Name of a GitHub organization."
echo " team Name of a GitHub team."
echo " teamMembersToIgnore Whitespace separated list of team members to ignore."
exit 1
}
create_fork=false
add_member_fork_remotes=false
while getopts :hfm opt; do
case $opt in
h) printHelp ;;
f) create_fork=true ;;
m) add_member_fork_remotes=true ;;
\?) echo "Unknown option -$OPTARG"; exit 1;;
esac
done
# remove the parsed options from the positional params
shift $(( OPTIND - 1 ))
ORGANIZATION=$1
TEAM=$2
if [[ -z "$2" ]]; then
printHelp
fi
RESPONSE="$(gh api graphql -f query="query { \
viewer { \
login \
} \
organization(login: \""$ORGANIZATION"\") { \
team(slug: \""$TEAM"\") { \
members(first: 100, orderBy: {field: LOGIN, direction: ASC}) { \
nodes { \
login \
} \
} \
repositories(first: 100, orderBy: {field: NAME, direction: ASC}) { \
nodes { \
sshUrl \
isArchived \
} \
} \
} \
} \
}" | jq '.data | { currentUser: .viewer.login, team: .organization.team }')"
CURRENT_USER="$(jq -r '.currentUser' <<< "${RESPONSE}")"
TEAM_MEMBERS="$(jq -r --arg CURRENT_USER "$CURRENT_USER" '.team.members.nodes[].login | select(. != $CURRENT_USER)' <<< "${RESPONSE}")"
REPOSITORIES="$(jq -r '.team.repositories.nodes[] | select(.isArchived==false) | .sshUrl' <<< "${RESPONSE}")"
if [[ -n "$3" ]]; then
shift; shift;
for teamMemberToIgnore
do
TEAM_MEMBERS=("${TEAM_MEMBERS/$teamMemberToIgnore}")
done
fi
function addRemote {
teamMember=$1
repository=$2
forkRepository=${repository/$ORGANIZATION/$teamMember}
echo "Adding remote for fork ${forkRepository}"
git remote add "${teamMember,,}" "${forkRepository}"
}
for repository in ${REPOSITORIES}
do
repositoryName=${repository##*/}
repositoryName=${repositoryName%.git}
gh repo clone "${repository}" -- -o upstream
cd "$repositoryName" || exit
if $create_fork; then
gh repo fork --remote=true
fi
if $add_member_fork_remotes; then
for teamMember in ${TEAM_MEMBERS}
do
addRemote "${teamMember}" "${repository}"
done
fi
cd ..
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment