Skip to content

Instantly share code, notes, and snippets.

@nathanbrauer
Forked from JonasGroeger/sync-projects
Last active February 4, 2020 21:14
Show Gist options
  • Save nathanbrauer/585cba6513fa2891d2fb45622017c6a6 to your computer and use it in GitHub Desktop.
Save nathanbrauer/585cba6513fa2891d2fb45622017c6a6 to your computer and use it in GitHub Desktop.
Gitlab: Clone / Pull all projects in a group
#!/usr/bin/env bash
# Documentation
# https://docs.gitlab.com/ce/api/projects.html#list-projects
if [[ `whoami` == "root" ]]; then
echo "DO NOT run this program as root! Quitting."
exit 1
fi
echo
echo "Enter the hostname for your GitLab instance."
echo "gitlab.example.com"
echo
read -p "REQUIRED: " HOSTNAME < /dev/tty
if [ -z "$HOSTNAME" ]; then
echo "You must provide a the hostname! Quitting."
exit 1
fi
echo
echo "Host key verification:"
echo
ssh-keyscan $HOSTNAME
echo
read -p "Are you sure you want to continue connecting (yes/no)? " HOST_KEY < /dev/tty
if [ "$HOST_KEY" != "yes" ]; then
echo "Host key verification failed. Quitting."
exit 1
fi
touch ~/.ssh/known_hosts
ssh-keyscan -t rsa,dsa ${HOSTNAME} 2>&1 | sort -u - ~/.ssh/known_hosts > ~/.ssh/tmp_hosts
mv ~/.ssh/tmp_hosts ~/.ssh/known_hosts
BASE_PATH="https://$HOSTNAME/"
echo
echo "Provide your Gitlab Private Token."
echo "See ${BASE_PATH}profile/account"
echo
read -p "REQUIRED: " GITLAB_PRIVATE_TOKEN < /dev/tty
if [ -z "$GITLAB_PRIVATE_TOKEN" ]; then
echo "Your Gitlab Private Token is required to move forward! Quitting."
exit 1
fi
echo
echo "Enter the GitLab group you'd like to clone repos from."
echo "E.g. ${BASE_PATH}GROUP_NAME_HERE/PROJECT_NAME_HERE"
echo
read -p "REQUIRED: " NAMESPACE < /dev/tty
if [ -z "$NAMESPACE" ]; then
echo "You must provide a group name! Quitting."
exit 1
fi
echo
echo "If you'd like to limit your download to specific search parameters, add your search parameter string here."
echo "See https://docs.gitlab.com/ce/api/projects.html#list-projects"
echo
read -p "OPTIONAL: " PROJECT_SEARCH_PARAM < /dev/tty
PROJECT_SELECTION="select(.namespace.name == \"$NAMESPACE\")"
PROJECT_PROJECTION="{ "path": .path, "git": .ssh_url_to_repo }"
FILENAME="repos.json"
echo
echo "And here we go..."
trap "{ rm -f $FILENAME; }" EXIT
curl -s "${BASE_PATH}api/v3/projects?private_token=$GITLAB_PRIVATE_TOKEN&search=$PROJECT_SEARCH_PARAM&per_page=999" \
| jq --raw-output --compact-output ".[] | $PROJECT_SELECTION | $PROJECT_PROJECTION" > "$FILENAME"
while read repo; do
THEPATH=$(echo "$repo" | jq -r ".path")
GIT=$(echo "$repo" | jq -r ".git")
if [ ! -d "$THEPATH" ]; then
echo "Cloning $THEPATH ( $GIT )"
git clone "$GIT" --quiet &
else
echo "Pulling $THEPATH"
(cd "$THEPATH" && git pull --quiet) &
fi
done < "$FILENAME"
wait
echo "All done!"
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment